#include "bms_Slave.h"
#include "bms_Slave_SOP.h"
#include "Alarm_Recov_sys.h"
#include <math.h>
#include "rtwtypes.h"
#include "ABI.h"
#include "look1_is16lu8n8tu8_binlcase.h"
#include "look1_iu16lftu8DfIf_binlcapw.h"
#include "plook_u8s16f_binc.h"
#include "plook_u8ff_binc.h"
#include "intrp2d_u16ffu8fl_pw.h"
#include "intrp2d_u8ffu8fl_pw.h"
#include "calPrms.h"
#include "ASW_Signal.h"

void bms_Slave_SOP_Init(void)
{
  bms_Slave_Alarm_Recov_sys_Init(&bms_Slave_B.Alarm_flg_jr);
  bms_Slave_Alarm_Recov_sys_Init(&bms_Slave_B.Alarm_flg_l);
  bms_Slave_Alarm_Recov_sys_Init(&bms_Slave_B.Alarm_flg_j);
  bms_Slave_Alarm_Recov_sys_Init(&bms_Slave_B.Alarm_flg);
  bms_Slave_Alarm_Recov_sys_Init(&bms_Slave_B.Alarm_flg_m);
}

void bms_Slave_SOP(void)
{
  int32_T i;
  int32_T rtb_Switch5;
  real32_T tmp[6];
  real32_T frac[2];
  real32_T frac_0[2];
  real32_T frac_1[2];
  real32_T frac_2[2];
  real32_T frac_3[2];
  real32_T frac_4[2];
  real32_T rtb_InterpolationUsingPrelookup[2];
  real32_T rtb_Divide;
  real32_T rtb_ThirtySecChrg;
  real32_T rtb_ThirtySecDisChrg;
  uint32_T tmp_0;
  uint8_T bpIndex[2];
  uint8_T bpIndex_0[2];
  uint8_T bpIndex_1[2];
  uint8_T bpIndex_2[2];
  uint8_T bpIndex_3[2];
  uint8_T bpIndex_4[2];
  uint8_T rtb_Prelookup8_o1_idx_1;
  boolean_T rtb_LogicalOperator4_a;
  rtb_LogicalOperator4_a = ((bms_Slave_B.SOC_Act < SOC_ReChrg) &&
    (bms_Slave_B.CellV_max >= CellV_Rechrg_limit));
  bms_Slave_Alarm_Recov_sys(rtb_LogicalOperator4_a, !rtb_LogicalOperator4_a, 20,
    200, &bms_Slave_B.Alarm_flg_jr, &bms_Slave_DW.sf_Alarm_Recov_ReCellV);
  if (bms_Slave_B.Current > 0.0F) {
    rtb_Switch5 = 0;
  } else {
    rtb_Divide = fmodf((real32_T)bms_Slave_B.Current, 4.2949673E+9F);
    rtb_Switch5 = rtb_Divide < 0.0F ? -(int32_T)-rtb_Divide : (int32_T)(uint32_T)
      rtb_Divide;
  }

  frac_1[1] = 0.0F - (real32_T)rtb_Switch5;
  rtb_ThirtySecDisChrg = 0.01F * bms_Slave_B.SOH;
  bms_Slave_DW.UnitDelay25_DSTATE = 0.01F * (real32_T)
    look1_is16lu8n8tu8_binlcase(bms_Slave_B.CellT_max, (const int16_T *)
    &CellT_SOP[0], (const uint8_T *)&SOP_DisChrg_CellTLimit[0], 8U);
  bms_Slave_DW.UnitDelay27_DSTATE = rtb_ThirtySecDisChrg * 10.0F *
    look1_iu16lftu8DfIf_binlcapw(bms_Slave_B.CellV_max, (const uint16_T *)
    &CellV_SOP[0], (const uint8_T *)&SOP_Chrg_Current[0], 11U) *
    bms_Slave_DW.UnitDelay25_DSTATE;
  bpIndex[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_ThirtySecChrg[0], 7U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_ThirtySecChrg[0], 7U, &rtb_InterpolationUsingPrelookup[1]);
  for (i = 0; i < 6; i++) {
    tmp[i] = SOC_ThirtySecChrg[i];
  }

  bpIndex[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &frac[1]);
  frac[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u16ffu8fl_pw(bpIndex, frac, (
    const uint16_T *)&ThirtySec_Power_Chrg[0], 8U);
  frac[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex[0] = rtb_Prelookup8_o1_idx_1;
  rtb_Divide = intrp2d_u16ffu8fl_pw(bpIndex, frac, (const uint16_T *)
    &ThirtySec_Power_Chrg[0], 8U);
  rtb_InterpolationUsingPrelookup[1] = rtb_Divide;
  rtb_Divide = fminf(rtb_InterpolationUsingPrelookup[0], rtb_Divide);
  frac_0[1] = rtb_Divide;
  rtb_ThirtySecChrg = bms_Slave_DW.UnitDelay27_DSTATE * fminf(rtb_Divide, 500.0F);
  bpIndex_0[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_ConChrg[0], 7U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_ConChrg[0], 7U, &rtb_InterpolationUsingPrelookup[1]);
  for (i = 0; i < 6; i++) {
    tmp[i] = SOC_ConChrg[i];
  }

  bpIndex_0[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &frac_0[1]);
  frac_0[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u8ffu8fl_pw(bpIndex_0, frac_0, (
    const uint8_T *)&Contious_Power_Chrg[0], 8U);
  frac_0[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex_0[0] = rtb_Prelookup8_o1_idx_1;
  rtb_InterpolationUsingPrelookup[1] = intrp2d_u8ffu8fl_pw(bpIndex_0, frac_0, (
    const uint8_T *)&Contious_Power_Chrg[0], 8U);
  bms_Slave_B.Con_AllowChrg_Current = bms_Slave_DW.UnitDelay27_DSTATE * fminf
    (fminf(rtb_InterpolationUsingPrelookup[0], rtb_InterpolationUsingPrelookup[1]),
     500.0F);
  bms_Slave_Alarm_Recov_sys((0.0F - (real32_T)rtb_Switch5) - rtb_ThirtySecChrg >
    0.0F, (0.0F - (real32_T)rtb_Switch5) - bms_Slave_B.Con_AllowChrg_Current <=
    0.0F, Con_Time, Con_Time, &bms_Slave_B.Alarm_flg_l,
    &bms_Slave_DW.sf_Alarm_Recov_SOP_Rechrg);
  if (bms_Slave_B.Current > 0.0F) {
    rtb_Switch5 = 0;
  } else {
    rtb_Divide = fmodf((real32_T)bms_Slave_B.Current, 4.2949673E+9F);
    rtb_Switch5 = rtb_Divide < 0.0F ? -(int32_T)-rtb_Divide : (int32_T)(uint32_T)
      rtb_Divide;
  }

  bpIndex_1[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_PuChrg[0], 7U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_PuChrg[0], 7U, &rtb_InterpolationUsingPrelookup[1]);
  for (i = 0; i < 6; i++) {
    tmp[i] = SOC_PuChrg[i];
  }

  bpIndex_1[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &frac_1[1]);
  frac_1[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u8ffu8fl_pw(bpIndex_1, frac_1, (
    const uint8_T *)&Pulse_Power_Chrg[0], 8U);
  frac_1[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex_1[0] = rtb_Prelookup8_o1_idx_1;
  rtb_InterpolationUsingPrelookup[1] = intrp2d_u8ffu8fl_pw(bpIndex_1, frac_1, (
    const uint8_T *)&Pulse_Power_Chrg[0], 8U);
  bms_Slave_DW.UnitDelay27_DSTATE *= fminf(fminf
    (rtb_InterpolationUsingPrelookup[0], rtb_InterpolationUsingPrelookup[1]),
    500.0F);
  bms_Slave_Alarm_Recov_sys((0.0F - (real32_T)rtb_Switch5) -
    bms_Slave_DW.UnitDelay27_DSTATE > 0.0F, (0.0F - (real32_T)rtb_Switch5) -
    rtb_ThirtySecChrg <= 0.0F, Pul_Time, Pul_Time, &bms_Slave_B.Alarm_flg_j,
    &bms_Slave_DW.sf_Alarm_Recov_SOP_Rechrg_l);
  rtb_Divide = look1_iu16lftu8DfIf_binlcapw(bms_Slave_B.CellV_min, (const
    uint16_T *)&CellV_SOP[0], (const uint8_T *)&SOP_DisChrg[0], 11U);
  rtb_ThirtySecDisChrg = rtb_ThirtySecDisChrg * 10.0F * rtb_Divide *
    bms_Slave_DW.UnitDelay25_DSTATE;
  bpIndex_2[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_ConDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_ConDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[1]);
  for (rtb_Switch5 = 0; rtb_Switch5 < 6; rtb_Switch5++) {
    tmp[rtb_Switch5] = SOC_ConDisChrg[rtb_Switch5];
  }

  bpIndex_2[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &rtb_Divide);
  frac_2[1] = rtb_Divide;
  frac_2[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u8ffu8fl_pw(bpIndex_2, frac_2, (
    const uint8_T *)&Contious_Power_DisChrg[0], 9U);
  frac_2[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex_2[0] = rtb_Prelookup8_o1_idx_1;
  rtb_Divide = intrp2d_u8ffu8fl_pw(bpIndex_2, frac_2, (const uint8_T *)
    &Contious_Power_DisChrg[0], 9U);
  rtb_InterpolationUsingPrelookup[1] = rtb_Divide;
  rtb_Divide = fminf(rtb_InterpolationUsingPrelookup[0], rtb_Divide);
  frac_3[1] = rtb_Divide;
  bms_Slave_B.Con_AllowDisChrg_Current = rtb_ThirtySecDisChrg * fminf(rtb_Divide,
    500.0F);
  bpIndex_3[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_PuDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_PuDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[1]);
  for (rtb_Switch5 = 0; rtb_Switch5 < 6; rtb_Switch5++) {
    tmp[rtb_Switch5] = SOC_PuDisChrg[rtb_Switch5];
  }

  bpIndex_3[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &frac_3[1]);
  frac_3[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u8ffu8fl_pw(bpIndex_3, frac_3, (
    const uint8_T *)&Pulse_Power_DisChrg[0], 9U);
  frac_3[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex_3[0] = rtb_Prelookup8_o1_idx_1;
  rtb_Divide = intrp2d_u8ffu8fl_pw(bpIndex_3, frac_3, (const uint8_T *)
    &Pulse_Power_DisChrg[0], 9U);
  rtb_InterpolationUsingPrelookup[1] = rtb_Divide;
  rtb_Divide = fminf(rtb_InterpolationUsingPrelookup[0], rtb_Divide);
  frac_4[1] = rtb_Divide;
  bms_Slave_DW.UnitDelay25_DSTATE = rtb_ThirtySecDisChrg * fminf(rtb_Divide,
    500.0F);
  bpIndex_4[0] = plook_u8s16f_binc(bms_Slave_B.CellT_max, (const int16_T *)
    &Temp_ThirtySecDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[0]);
  rtb_Prelookup8_o1_idx_1 = plook_u8s16f_binc(bms_Slave_B.CellT_min, (const
    int16_T *)&Temp_ThirtySecDisChrg[0], 8U, &rtb_InterpolationUsingPrelookup[1]);
  for (rtb_Switch5 = 0; rtb_Switch5 < 6; rtb_Switch5++) {
    tmp[rtb_Switch5] = SOC_ThirtySecDisChrg[rtb_Switch5];
  }

  bpIndex_4[1] = plook_u8ff_binc(bms_Slave_B.SOC_Act, tmp, 5U, &frac_4[1]);
  frac_4[0] = rtb_InterpolationUsingPrelookup[0];
  rtb_InterpolationUsingPrelookup[0] = intrp2d_u16ffu8fl_pw(bpIndex_4, frac_4, (
    const uint16_T *)&ThirtySec_Power_DisChrg[0], 9U);
  frac_4[0] = rtb_InterpolationUsingPrelookup[1];
  bpIndex_4[0] = rtb_Prelookup8_o1_idx_1;
  rtb_ThirtySecDisChrg *= fminf(fminf(rtb_InterpolationUsingPrelookup[0],
    intrp2d_u16ffu8fl_pw(bpIndex_4, frac_4, (const uint16_T *)
    &ThirtySec_Power_DisChrg[0], 9U)), 500.0F);
  bms_Slave_DW.Relay_Mode = ((bms_Slave_B.SOC_Act >= SOC_ReChrg + 0.5F) ||
    ((!(bms_Slave_B.SOC_Act <= SOC_ReChrg)) && bms_Slave_DW.Relay_Mode));
  rtb_LogicalOperator4_a = (bms_Slave_DW.Relay_Mode || bms_Slave_B.Alarm_flg_jr);
  if (bms_Slave_B.Current > 0.0F) {
    rtb_Switch5 = (int32_T)fmodf((real32_T)bms_Slave_B.Current, 4.2949673E+9F);
  } else {
    rtb_Switch5 = 0;
  }

  bms_Slave_Alarm_Recov_sys((real32_T)rtb_Switch5 - rtb_ThirtySecDisChrg > 0.0F,
    (real32_T)rtb_Switch5 - bms_Slave_B.Con_AllowDisChrg_Current <= 0.0F,
    Con_Time, Con_Time, &bms_Slave_B.Alarm_flg,
    &bms_Slave_DW.sf_Alarm_Recov_SOP_Dischrg_g);
  if (!bms_Slave_B.Alarm_flg) {
    bms_Slave_B.Con_AllowDisChrg_Current = rtb_ThirtySecDisChrg;
  }

  if (ABI_AdcSamplingData.Bat_Vol > 0U) {
    tmp_0 = ABI_AdcSamplingData.Bat_Vol;
  } else {
    tmp_0 = (uint32_T)CellV_Rate * CellV_num;
  }

  rtb_Divide = fminf(bms_Slave_B.Con_AllowDisChrg_Current, 400000.0F / (real32_T)
                     tmp_0 * 1000.0F);
  if (bms_Slave_B.UnitDelay21) {
    bms_Slave_DW.UnitDelay_DSTATE_g -= (bms_Slave_B.Con_AllowDisChrg_Current -
      rtb_Divide) * 0.000167F;
    if (bms_Slave_DW.UnitDelay_DSTATE_g <= 0.0F) {
      bms_Slave_DW.UnitDelay_DSTATE_g = 0.0F;
    }
  } else {
    bms_Slave_DW.UnitDelay_DSTATE_g = bms_Slave_B.Con_AllowDisChrg_Current -
      rtb_Divide;
  }

  if (bms_Slave_B.Current > 0.0F) {
    rtb_Switch5 = (int32_T)fmodf((real32_T)bms_Slave_B.Current, 4.2949673E+9F);
  } else {
    rtb_Switch5 = 0;
  }

  bms_Slave_Alarm_Recov_sys((real32_T)rtb_Switch5 -
    bms_Slave_DW.UnitDelay25_DSTATE > 0.0F, (real32_T)rtb_Switch5 -
    rtb_ThirtySecDisChrg <= 0.0F, Pul_Time, Pul_Time, &bms_Slave_B.Alarm_flg_m,
    &bms_Slave_DW.sf_Alarm_Recov_SOP_Dischrg);
  if (bms_Slave_B.Alarm_flg_m) {
    bms_Slave_DW.UnitDelay25_DSTATE = rtb_ThirtySecDisChrg;
  }

  if (ABI_AdcSamplingData.Bat_Vol > 0U) {
    tmp_0 = ABI_AdcSamplingData.Bat_Vol;
  } else {
    tmp_0 = (uint32_T)CellV_Rate * CellV_num;
  }

  rtb_ThirtySecDisChrg = fminf(bms_Slave_DW.UnitDelay25_DSTATE, 400000.0F /
    (real32_T)tmp_0 * 1000.0F);
  if (bms_Slave_B.UnitDelay21) {
    bms_Slave_DW.UnitDelay_DSTATE_i -= (bms_Slave_DW.UnitDelay25_DSTATE -
      rtb_ThirtySecDisChrg) * 0.000167F;
    if (bms_Slave_DW.UnitDelay_DSTATE_i <= 0.0F) {
      bms_Slave_DW.UnitDelay_DSTATE_i = 0.0F;
    }
  } else {
    bms_Slave_DW.UnitDelay_DSTATE_i = bms_Slave_DW.UnitDelay25_DSTATE -
      rtb_ThirtySecDisChrg;
  }

  if ((bms_Slave_B.Relay_En == 0) || bms_Slave_DW.UnitDelay16_DSTATE ||
      (bms_Slave_B.SOC_Rpt <= 0.0F) || (bms_Slave_B.SOC_Act <= 0.0F)) {
    bms_Slave_DW.UnitDelay25_DSTATE = 0.0F;
  } else if (bms_Slave_B.UnitDelay21) {
    bms_Slave_DW.UnitDelay25_DSTATE = bms_Slave_DW.UnitDelay_DSTATE_i +
      rtb_ThirtySecDisChrg;
  }

  if ((bms_Slave_B.Relay_En == 0U) || rtb_LogicalOperator4_a ||
      bms_Slave_DW.UnitDelay18_DSTATE) {
    bms_Slave_B.Con_AllowChrg_Current = 0.0F;
  } else if (bms_Slave_B.UnitDelay17) {
    if (!bms_Slave_B.Alarm_flg_l) {
      bms_Slave_B.Con_AllowChrg_Current = rtb_ThirtySecChrg;
    }

    bms_Slave_B.Con_AllowChrg_Current *= 0.5F;
  } else if (!bms_Slave_B.Alarm_flg_l) {
    bms_Slave_B.Con_AllowChrg_Current = rtb_ThirtySecChrg;
  }

  if ((bms_Slave_B.Relay_En == 0) || bms_Slave_DW.UnitDelay16_DSTATE ||
      (bms_Slave_B.SOC_Rpt <= 0.0F) || (bms_Slave_B.SOC_Act <= 0.0F)) {
    bms_Slave_B.Con_AllowDisChrg_Current = 0.0F;
  } else if (bms_Slave_B.UnitDelay21) {
    bms_Slave_B.Con_AllowDisChrg_Current = bms_Slave_DW.UnitDelay_DSTATE_g +
      rtb_Divide;
  }

  if ((bms_Slave_B.Relay_En == 0U) || rtb_LogicalOperator4_a ||
      bms_Slave_DW.UnitDelay18_DSTATE) {
    bms_Slave_DW.UnitDelay27_DSTATE = 0.0F;
  } else if (bms_Slave_B.UnitDelay17) {
    if (bms_Slave_B.Alarm_flg_j) {
      bms_Slave_DW.UnitDelay27_DSTATE = rtb_ThirtySecChrg;
    }

    bms_Slave_DW.UnitDelay27_DSTATE *= 0.5F;
  } else if (bms_Slave_B.Alarm_flg_j) {
    bms_Slave_DW.UnitDelay27_DSTATE = rtb_ThirtySecChrg;
  }
}
